import { QWebChannel } from './qwebchannel';
import store from '@/store';
//add by guanjun20221109 富易CFCA证书通用方法
fqlCryptokit.cefAuthKey = 'gtja-7866';
fqlCryptokit.productID = 'com.gtja.cryptokit.fuyi';

fqlCryptokit.extensionName = fqlCryptokit.productID + '.extension';
fqlCryptokit.reqEventName = fqlCryptokit.productID + '.request';
fqlCryptokit.respEventName = fqlCryptokit.productID + '.response';
fqlCryptokit.qtLoaded = false;
fqlCryptokit.type = 2; //1:qt;2:cef
fqlCryptokit.SendMap = new Map();

fqlCryptokit.Browser = {
  Chrome: 'Chrome',
  Edge: 'Edge(Chromium)'
};

//初始化QTWeb信号槽
var INIT_QTWEB = function()
{
    if (typeof qt != 'undefined')
    {
        new QWebChannel(qt.webChannelTransport, function(channel)
        {
            window.qt_external = channel.objects.external;
            window.SendMessageforCEF = qt_external.SendMessageforCEF;
            qt_external.fyResponseInterFace.connect(FyResponseInterFace);
            fqlCryptokit.qtLoaded = true;
            qtCreated();
          })
    }
    else
    {
    }
}

var FyResponseInterFace = function(res)
{   
    let rJson = JSON.parse(res)
    let rId = rJson.randomId;
    if(rId != "")
    {
      let SendR = fqlCryptokit.SendMap.get(rId);
      let callback = SendR.qtCallback;
      callback.call(this, rJson);
      fqlCryptokit.SendMap.delete(rId);
    }
    
}

function qtCreated(){
    console.info('qtCreated');
    store.dispatch('initFqlCryptoKit');
}

function RefreshForm()
{
  javascript.location.href = self;
}

function GenerateRandomId () {
  var charstring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
  var maxPos = charstring.length;
  var randomId = '';
  for (var i = 0; i < 10; i++) {
    randomId += charstring.charAt(Math.floor(Math.random() * maxPos));
  }
  return randomId;
}

export function fqlCryptokit (browser,type) {
    if(type == 1)
    {
      INIT_QTWEB();
      this.type = type;
    }
    this.browser = browser;
};

fqlCryptokit.SendMessagebyEvent = function (request) {
  var event = new CustomEvent(fqlCryptokit.reqEventName, { detail: request });
  document.dispatchEvent(event);

  return new Promise(function (resolve, reject) {
    var responseEventName = fqlCryptokit.respEventName;
    if (request.funcInfo != undefined && request.funcInfo.randomId != undefined) { responseEventName += ('.' + request.funcInfo.randomId); }

    document.addEventListener(responseEventName, function CallBack (e) {
      document.removeEventListener(e.type, CallBack);
      var eJson = JSON.parse(e.detail);
      if (eJson != null && eJson.errorcode == 0) {
        resolve(eJson);
      } else {
        reject(eJson);
      }
    }, false);
  });
};

// Encapsulate cef sendMessage callback to Promise
fqlCryptokit.SendMessageforCEF = function (request) {
  
  return new Promise(function (resolve, reject) {
      let message = JSON.stringify(request);
      window.FYQuery({
        request: message,
        onSuccess: function (response) {
          resolve(JSON.parse(response));
        },
        onFailure: function (error_code, error_message) {
          var result = new Object();
            result.errorcode = error_code;
            result.result = error_message;
            reject(result);
        }
      });
  });
};

// Encapsulate cef sendMessage callback to Promise
fqlCryptokit.SendMessageforQT = function (request) {
  
  return new Promise(function (resolve, reject) {
    if (typeof window.qt_external == 'undefined') 
    {
      throw new Error('fql.error');
    }
    else
    {
       function callback(response) {
          if (response) {
            if (response.errorcode == 0) {
              resolve(response);
            } else {
              reject(response);
            }
          } else {
            var result = new Object();
            result.errorcode = 1;
            result.result = 'fql.error';
            reject(result);
          }
       }

        var FQLReq = {
            randomId: request.randomId , 
            qtCallback: function(res){
                callback(res);
            }
       }
       fqlCryptokit.SendMap.set(request.randomId,FQLReq)
       let sReq = JSON.stringify(request);
       window.SendMessageforCEF(sReq);
    }
  });
};

function jsCallLog(func,param)
{
  document.log("jsCallLog:"+func+param)
}

fqlCryptokit.SendMessage = function (browser, requestJSON) {
  if (fqlCryptokit.Browser.Chrome == browser || fqlCryptokit.Browser.Edge == browser) {
    if(fqlCryptokit.type == 1){
      return fqlCryptokit.SendMessageforQT(requestJSON);
    }
    else {
      return fqlCryptokit.SendMessageforCEF(requestJSON);
    }
    
  }
  else {
    return fqlCryptokit.SendMessagebyEvent(requestJSON);
  }
};

fqlCryptokit.checkExtension = function (browser) {
  return new Promise(function (resolve, reject) {
    var result = new Object();
    if (fqlCryptokit.Browser.Chrome == browser || fqlCryptokit.Browser.Edge == browser) {
      if (typeof window.qt_external == 'undefined') {
        result.errorcode = -1;
        result.result = 'qt does not init!';
        resolve(browser);
      } else {
        result.errorcode = 1;
        result.result = 'qt already!';
        resolve(browser);
      }
    } else {
      result.errorcode = -1;
      result.result = 'Only support FY.CEF';
      reject(result);
    }
  });
};

fqlCryptokit.prototype.init = function () {
  var browser = this.browser;

  return fqlCryptokit.checkExtension(browser)
      .then(function (browser) {
        var request = new Object();
        var funcInfo = new Object();
        var randomId = GenerateRandomId();
        funcInfo.function = 'connect';
        request.action = 'init';
        request.host = fqlCryptokit.productID;
        request.funcInfo = funcInfo;
        request.randomId = randomId;
        return fqlCryptokit.SendMessage(browser, request);
      }).then(function () {
        var request = new Object();
        var funcInfo = new Object();
        var randomId = GenerateRandomId();
        funcInfo.function = 'checkHost';
        funcInfo.params = null;
        funcInfo.randomId = randomId;
        request.action = 'invoke';
        request.funcInfo = funcInfo;
        request.randomId = randomId;
        return fqlCryptokit.SendMessage(browser, request);
      });
};

fqlCryptokit.prototype.getExtensionVersion = function () {
  var request = new Object();
  var funcInfo = new Object();
  var randomId = GenerateRandomId();

  funcInfo.function = 'getExtensionVersion';
  funcInfo.params = null;
  funcInfo.randomId = randomId;
  request.action = 'getExtensionVersion';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};

fqlCryptokit.prototype.getHostVersion = function () {
  var request = new Object();
  var funcInfo = new Object();
  var randomId = GenerateRandomId();

  funcInfo.function = 'GetVersion';
  funcInfo.params = null;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};


fqlCryptokit.prototype.selectCertificate = function (strSubjectDNFilter, strIssuerDNFilter, strSerialNo, strCSPNameList) {
  var request = new Object();
  var funcInfo = new Object();
  var paramArr = new Array();
  var randomId = GenerateRandomId();

  paramArr.push(strSubjectDNFilter);
  paramArr.push(strIssuerDNFilter);
  paramArr.push(strSerialNo);
  paramArr.push(strCSPNameList);

  funcInfo.function = 'SelectCertificate';
  funcInfo.params = paramArr;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};

fqlCryptokit.prototype.signFilePKCS7Detached = function (strFile, strSelectedAlg) {
  var request = new Object();
  var funcInfo = new Object();
  var paramArr = new Array();
  var randomId = GenerateRandomId();

  paramArr.push(strFile);
  paramArr.push(strSelectedAlg);

  funcInfo.function = 'SignFilePKCS7Detached';
  funcInfo.params = paramArr;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;

  return nmCryptokit.SendMessage(this.browser, request);
};

fqlCryptokit.prototype.getSignCertInfo = function (strInfoType) {
  var request = new Object();
  var funcInfo = new Object();
  var paramArr = new Array();
  var randomId = GenerateRandomId();

  paramArr.push(strInfoType);

  funcInfo.function = 'GetSignCertInfo';
  funcInfo.params = paramArr;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};

fqlCryptokit.prototype.signMsgPKCS7 = function (strSource, strSelectedAlg, bAttached) {
  var request = new Object();
  var funcInfo = new Object();
  var paramArr = new Array();
  var randomId = GenerateRandomId();

  paramArr.push(strSource);
  paramArr.push(strSelectedAlg);
  paramArr.push(bAttached);

  funcInfo.function = 'SignMsgPKCS7';
  funcInfo.params = paramArr;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};

fqlCryptokit.prototype.signMsgPKCS1 = function (strSource, strSelectedAlg) {
  var request = new Object();
  var funcInfo = new Object();
  var paramArr = new Array();
  var randomId = GenerateRandomId();

  paramArr.push(strSource);
  paramArr.push(strSelectedAlg);

  funcInfo.function = 'SignMsgPKCS1';
  funcInfo.params = paramArr;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};

fqlCryptokit.prototype.getLastErrorDesc = function () {
  var request = new Object();
  var funcInfo = new Object();
  var randomId = GenerateRandomId();

  funcInfo.function = 'GetLastErrorDesc';
  funcInfo.params = null;
  funcInfo.randomId = randomId;

  request.action = 'invoke';
  request.funcInfo = funcInfo;
  request.randomId = randomId;

  return fqlCryptokit.SendMessage(this.browser, request);
};
